#  Structs used for working with object permissions:
#
#  CfgACL - Access List struct
#   in CME it is object Security, window Object Permissions
#   Consists of:
#     objectID - reference to the object (CfgID struct)
#     count - number of permissions
#     ACEs - list of CfgACE structs (permissions)
#
#  CfgACE - Access List Element struct (my guess; there is no description)
#   In CME it is visible after selecting specific Permission from the Object Permissions
#   Consists of:
#     objectID - reference to the object (CfgID struct) this permission belongs to, either CfgAccessGroup or CfgPerson
#     accessMask - permission bit mask (7 bits), in this order: 'PEDXHCR'
#
#  CfgID - unique object ID
#     CSID - reserved, always 0
#     DBID - object DBID
#     type - object type
#
#  QAART Cfg object methods to work with ACL/ACEs
#
#  def GetACL(self) - retrieves object ACL from CS, sets to self.ACL
#
#  def GetACEByObjectID(self, objectID) - returns CfgACE
#    #objectID - struct CfgID, use <object>.cfgID
#
#  def ChangeACE(self, objectID, newMask, isRecursive = 1)
#    #objectID - struct CfgID, use <object>.cfgID
#    #newMask - string of symbols 'P', 'E', 'D', 'X', 'H', 'C', 'R'
#
#
#  def AddACE(self, objectID, maskString, isRecursive = 1) - adds ACE to self.ACL and sends request SetACL to CS
#    #ace - struct CfgACE
#    #maskString - string of symbols 'P', 'E', 'D', 'X', 'H', 'C', 'R'
#
#  def RemoveACE(self, objectID, isRecursive = 1) - removes ACE for objectID from self.ACL and sends request SetACL to CS
#    #objectID - struct CfgID, use <object>.cfgID
#
#  For further information refer to file /tester/cfg/model_cfgobject.py and cfglib.h


def test_acl():

  #-----------------------------------
  #names of existing and new objects
  tenantName = "Froggy"
  switchName = "G3_SIM_"
  parentFolderName = "DNs"
  newFolderName = "NEW FROGGY DNS"
  dnName = "101"
  personName = "FroggyPerson"
  #-----------------------------------

  #reading existing objects
  ownerSwitch = CfgSwitch(tenantName, switchName)

  print "================================================================="
  print parentFolderName, ownerSwitch.name, CfgObjectType.CFGSwitch,  ownerSwitch.name, CfgObjectType.CFGSwitch
  print "================================================================="

  parentFolder = CfgFolder(name = parentFolderName, ownerName = ownerSwitch.name, ownerType = CfgObjectType.CFGSwitch,  parentName = ownerSwitch.name, parentType = CfgObjectType.CFGSwitch)

  #Prepare new folder
  ownerID = ownerSwitch.cfgID
  newDNFolder  = CfgFolder()

  newDNFolder.SetAttributes({"name": newFolderName,
                             "type": CfgObjectType.CFGDN,
                             "ownerID": ownerID})
  #Add new folder to the parentFolder
  newDNFolder.AddToFolder(parentFolder)
  raw_input("Check folder %s created" %newFolderName)

  #DN <dnName> exists under folder DNs
  #Lets move it to <newFolderName>

  Dn = CfgDN(tenantName, switchName, dnName)

  Dn.MoveToFolder(newDNFolder)
  raw_input("Check DN 101 moved to the folder %s"%newFolderName)

  #read person, get cfgID
  personID = CfgPerson(tenantName, personName).cfgID

  #add new ACE - permissions for personID
  #by default - recursive, means Dn also gets the same permissions
  newDNFolder.AddACE(personID, "PEDX")
  raw_input("Check Folder %s  and DN %s ACL, for %s should be PEDX" %(newFolderName, dnName, personName))


  #change permission mask for personID in Dn
  Dn.ChangeACE(personID, newMask = "PH")

  raw_input("Check DN 101 ACL, for %s should be PH" %personName)

  #Remove ACE from folder ACL, isRecursive = 0, Dn ACL should not change
  newDNFolder.RemoveACE(personID, isRecursive = 0)
  raw_input("Check Folder %s  and DN %s ACL, no more person %s for the folder, person still for DN" %(newFolderName, dnName, personName))

  #change permission mask for personID in Dn, set Full Access
  Dn.ChangeACE(personID, newMask = "PEDXHCR")
  raw_input("Check DN 101 ACL, for %s should be FullControl" %personName)


  #test cleanup
  #move DN back
  Dn.MoveToFolder(parentFolder)
  #delete new folder
  newDNFolder.Delete()
  raw_input("Check folder deleted")


